<?php

namespace app\common\business;

use app\common\model\mysql\Category as CategoryModel;
use app\common\lib\Arr;

/**
 * Class Category
 * @package app\common\business
 */
class Category {
    public $model = null;

    public function __construct() {
        $this->model = new CategoryModel();
    }

    /**
     * 添加分类
     * @param $data
     * @return mixed
     * @throws \think\Exception
     */
    public function add($data) {
        $data['status'] = config('status.mysql.table_normal');
        // 根据$name 去数据库查询是否存在这条记录
        $res = $this->model->getCategoryByName($data['name']);
        if ($res) {
            throw new \think\Exception('分类名已存在');
        }

        $path = '';
        // 获取父级分类的path
        if ($data['pid'] !== 0) {
            $res = $this->model->getCategoryById($data['pid']);
            $path = $res['path'];
        }

        // 开启事务
        $this->model->startTrans();

        try {
            // 首先保存分类名
            $this->model->save($data);
            // 更新path
            $id = $this->model->id;
            $path = $path ? $path . ',' . $id : $id;
            $data = [
                'path' => $path
            ];
            $this->model->updateById($id, $data);
            $this->model->commit();
        } catch (\Exception $e) {
            //事务回滚
            $this->model->rollback();
            throw new \think\Exception('服务内部异常');
        }
        return $id;
    }

    public function getNormalCategorys() {
        $field = 'id, name, pid';
        $category = $this->model->getNormalCategorys($field);
        if (!$category) {
            return $category;
        }
        $category = $category->toArray();
        return $category;
    }

    public function getNormalAllCategorys() {
        $field = 'id as category_id, name, pid';
        $category = $this->model->getNormalCategorys($field);
        if (!$category) {
            return $category;
        }
        $category = $category->toArray();
        return $category;
    }

    public function getLists($data, $num) {
        $list = $this->model->getLists($data, $num);
        if (!$list) {
            return [];
        }

        $result = $list->toArray();
        $result['render'] = $list->render();

        // 获取分类子类数目
        $pids = array_column($result['data'], 'id');
        if ($pids) {
            $idCountResult = $this->model->getChildCountInPids(['pid' => $pids]);
            $idCountResult = $idCountResult->toArray();
            $idCounts = [];
            foreach ($idCountResult as $countResult) {
                $idCounts[$countResult['pid']] = $countResult['count'];
            }
        }
        if ($result['data']) {
            foreach ($result['data'] as $k => $value) {
                /// $a ?? 0 等同于 isset($a) ? $a : 0。
                $result['data'][$k]['childCount'] = $idCounts[$value['id']] ?? 0;
            }
        }

        return $result;
    }

    /**
     * 根据id获取某一条记录
     * @param $id
     * @return array
     */
    public function getById($id) {
        try {
            $result = $this->model->find($id);
        } catch (\Exception $e) {
            return [];
        }

        $result = $result->toArray();
        return $result;
    }

    /**
     * 排序
     * @param $id
     * @param $listorder
     * @return bool
     * @throws \think\Exception
     */
    public function listorder($id, $listorder) {
        // 查询 id这条数据是否存在
        $res = $this->getById($id);
        if (!$res) {
            throw new \think\Exception('不存在该条记录');
        }
        $data = [
            'listorder' => $listorder,
        ];

        try {
            $res = $this->model->updateById($id, $data);
        } catch (\Exception $e) {
            return false;
        }
        return $res;
    }

    /**
     * 修改状态
     * @param $id
     * @param $status
     * @return array|bool|\think\Model|void|null
     * @throws \think\Exception
     */
    public function status($id, $status) {
        $res = $this->getById($id);
        if (!$res) {
            throw new \think\Exception('不存在该条记录');
        }
        if ($res['status'] == $status) {
            throw new \think\Exception('状态无改变');
        }

        $data = [
            'status' => intval($status),
        ];

        try {
            $res = $this->model->updateById($id, $data);
        } catch (\Exception $e) {
            return false;
        }
        return $res;
    }

    /**
     * 获取一级分类的内容
     * @param int $pid
     * @param string $field
     * @return array
     */
    public function getNormalByPid($pid, $field = 'id, name, pid') {
        try {
            $res = $this->model->getNormalByPid($pid, $field);
        } catch (\Exception $e) {
            return [];
        }
        return $res->toArray();
    }

    /**
     * 获取一级分类的内容
     * @param array $pids
     * @param string $field
     * @return array
     */
    public function getNormalByPids($pids, $field = 'id, name, pid') {
        try {
            $res = $this->model->getNormalByPids($pids, $field);
        } catch (\Exception $e) {
            return [];
        }
        return $res->toArray();
    }

    /**
     * @param $id
     * @return array
     */
    public function search($id) {
        try {
            $result = [];
            $res = $this->model->getCategoryById($id);
            // 获取path值
            $path = explode(',', $res['path']);
            $result['focus_ids'] = array_map('intval', array_slice($path, 1));
            array_pop($path); // 删除最后一个元素
            // 获取子分类list
            if (count($path) == 0) { //如果是一级分类则获取他下面的二级分类
                $result['list'][0] = $this->getNormalByPid($res['id'], 'id, name');
            } else { // 如果是二级和三级分类，则获取同pid的所有分类
                // 获取一级分类名称
                $res = $this->model->getCategoryById($path[0], 'name');
                foreach ($path as $k => $v) {
                    $result['list'][$k] = $this->getNormalByPid($v, 'id, name');
                }
            }
            $result['name'] = $res['name'];
        } catch (\Exception $e) {
            //记录日志
            return Arr::defaultSearch();
        }
        return $result;
    }
}